package com.wzl.thread.pool;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

/**
 * Java内置线程池-子接口: ScheduledExecutorService
 *
 * 创建一个定长的线程池，可以指定线程池核心线程数，支持定时及周期性任务的执行
 *
 *  schedule(Runnable command, long delay, TimeUnit unit)，延迟一定时间后执行Runnable任务；
 *  schedule(Callable callable, long delay, TimeUnit unit)，延迟一定时间后执行Callable任务；
 *  scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)，延迟一定时间后，以间隔period时间的频率周期性地执行任务；
 *  scheduleWithFixedDelay(Runnable command, long initialDelay, long delay,TimeUnit unit)，与scheduleAtFixedRate()方法很类似，
 *  但是不同的是scheduleWithFixedDelay()方法的周期时间间隔是以上一个任务执行结束到下一个任务开始执行的间隔，而scheduleAtFixedRate()方法的周期时间间隔是以上一个任务开始执行到下一个任务开始执行的间隔，
 *  也就是这一些任务系列的触发时间都是可预知的。
 *  ScheduledExecutorService功能强大，对于定时执行的任务，建议多采用该方法。
 *
 * @author weizhongli
 * @since 2022-09-19 11:07
 */
@Slf4j
public class TcNewScheduledThreadPool {

    /**
     * 通过schedule()延迟执行任务的功能
     */
    public static void schedule(){
        //1.获取一个具备延迟执行任务的线程池对象
        ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3);
        for (int i = 0; i < 5; i++) {
            int finalI = i;
            executorService.schedule(() -> {
                log.info("线程执行啦.......哈哈哈哈哈哈" + finalI + "----" + Thread.currentThread().getName());
            },2,TimeUnit.SECONDS);
        }


    }

    /**
     * scheduleAtFixedRate() 延迟执行任务和重复执行任务的功能
     */
    public static void scheduleAtFixedRate(){
        ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3, new ThreadFactory() {
            int n = 1;
            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r, "自定义线程名称：" + n++);
            }
        });
        for (int i = 0; i < 5; i++) {
            int finalI = i;
            //2.创建多个任务对象，提交任务，每个任务延迟2秒执行        //初始等待1秒，执行任务间隔2秒
            executorService.scheduleAtFixedRate(() ->
                            log.info("线程执行啦.......哈哈哈哈哈哈" + finalI + "----" + Thread.currentThread().getName()),
                    1, 2, TimeUnit.SECONDS);
        }
    }

    /**
     * scheduleWithFixedDelay() 延迟执行任务和重复执行任务的功能
     */
    public static void scheduleWithFixedDelay(){
        //1.获取一个具备延迟执行任务的线程池对象
        ScheduledExecutorService es = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
            int n = 1;
            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r,"自定义线程名称：" + n++);
            }
        });
        for (int i = 0; i < 5; i++) {
            int finalI = i;
            //2.创建多个任务对象，提交任务，每个任务延迟2秒执行        //初始延迟1秒，执行任务间隔2秒（任务执行时间不计入的，是等任务执行之后再间隔2秒）
            es.scheduleWithFixedDelay(() -> log.info("线程执行啦.......哈哈哈哈哈哈" + finalI + "----" + Thread.currentThread().getName()), 1, 2, TimeUnit.SECONDS);
        }


    }

}